package com.epoint.JenkinsExtension;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import org.dom4j.Element;

import java.io.*;
import java.net.URLEncoder;
import java.util.List;


public class JenkinsClient {

    private static ClientInfo clientInfo;
    private static JenkinsClient client = null;

    private JenkinsClient() {
    }

    private JenkinsClient(ClientInfo info) {
        this.clientInfo = info;
    }

    public static synchronized JenkinsClient getInstance(ClientInfo info) {
        if (client == null) {
            client = new JenkinsClient(info);
        }
        return client;
    }

    /**
     * 获取jenkins的Crumb
     * @throws Exception
     */
    public void InitCrumb() throws Exception {
        HttpResponse<String> response = Unirest.get(clientInfo.getUrl() + "crumbIssuer/api/json")
                .basicAuth(clientInfo.getUserName(), clientInfo.getPassWord())
                .header("cache-control", "no-cache")
                .asString();

        JSONObject jsonobject = JSON.parseObject(response.getBody());
        if (!"OK".equals(response.getStatusText())) {
            throw new Exception(response.getStatusText());
        }
        clientInfo.setCrumb(jsonobject.get("crumb").toString());
    }

    /**
     * 获取任务的详细配置
     * @param jobName 任务名
     * @return 任务xml
     * @throws Exception
     */
    public String GetJobConfig(String jobName) throws Exception {
        HttpResponse<String> response = Unirest.get(clientInfo.getUrl() + "job/" + jobName + "/config.xml")
                .basicAuth(clientInfo.getUserName(), clientInfo.getPassWord())
                .header("cache-control", "no-cache")
                .asString();
        if (!"OK".equals(response.getStatusText())) {
            throw new Exception(response.getStatusText());
        }
        return response.getBody();
    }

    /**
     * 通过xml文件创建job
     *
     * @param jobName 任务名
     */
    public void CreateItem(String jobName, String jobConfig) throws Exception {
        if (!CheckJobExist(jobName)) {
            PostConfigXml(clientInfo.getUrl() + "createItem?name=" + jobName, jobName, jobConfig);
        } else {
            throw new Exception("任务已存在，创建失败");
        }
    }

    /**
     * 如果job已经创建了，就进行构建
     * @param jobName 任务名
     * @param jobConfig 任务详细配置xml
     * @throws Exception
     */
    public void CreateItemAndBuild(String jobName, String jobConfig) throws Exception {
        if (!CheckJobExist(jobName)) {
            PostConfigXml(clientInfo.getUrl() + "createItem?name=" + jobName, jobName, jobConfig);
        } else {
            this.Build(jobName);
        }
    }

    /**
     * 构建镜像
     *
     * @param jobName 任务名称
     */
    public String Build(String jobName) throws Exception {
        jobName = URLEncoder.encode(jobName, "UTF-8");
        HttpResponse<String> response = Unirest.post(clientInfo.getUrl() + "job/" + jobName + "/build")
                .basicAuth(clientInfo.getUserName(), clientInfo.getPassWord())
                .header("Jenkins-Crumb", clientInfo.getCrumb())
                .header("Content-Type", "application/xml")
                .header("cache-control", " no-cache")
                .header("accept-encoding", "gzip, deflate")
                .asString();
        if (!"OK".equals(response.getStatusText())) {
            throw new Exception(response.getStatusText());
        }
        return response.getStatusText();
    }

    /**
     * 更新配置
     *
     * @param jobName 任务名
     */
    public void UpdateConfig(String jobName, String jobConfig) throws Exception {
        PostConfigXml(clientInfo.getUrl() + "job/" + jobName + "/config.xml", jobName, jobConfig);
    }

    /**
     * Post config Xml
     *
     * @param url     api url
     * @param jobName 任务名
     */
    private void PostConfigXml(String url, String jobName, String xmlContent) throws Exception {
//        StringBuffer buffer = new StringBuffer();
//        BufferedReader bf = new BufferedReader(new FileReader(xmlPath));
//        String s = null;
//        while ((s = bf.readLine()) != null) {//使用readLine方法，一次读一行
//            buffer.append(s.trim());
//        }
//        String xml = buffer.toString();
        jobName = URLEncoder.encode(jobName, "UTF-8");
        HttpResponse<String> response = Unirest.post(url)
                .basicAuth(clientInfo.getUserName(), clientInfo.getPassWord())
                .header("Jenkins-Crumb", clientInfo.getCrumb())
                .header("Content-Type", "application/xml")
                .header("cache-control", " no-cache")
                .header("accept-encoding", "gzip, deflate")
                .body(xmlContent)
                .asString();
    }

    private void LoadConfig(String jobName) throws Exception {
        jobName = URLEncoder.encode(jobName, "UTF-8");
        HttpResponse<InputStream> response = Unirest
                .get(clientInfo.getUrl() + "job/" + jobName + "/config.xml")
                .basicAuth(clientInfo.getUserName(), clientInfo.getPassWord())
                .asBinary();
        Document dom = new SAXReader().read(response.getBody());
    }

    private boolean CheckJobExist(String jobName) throws Exception {
        HttpResponse<InputStream> response = Unirest.post(clientInfo.getUrl() + "api/xml?tree=jobs[name]")
                .basicAuth(clientInfo.getUserName(), clientInfo.getPassWord())
                .header("Jenkins-Crumb", clientInfo.getCrumb())
                .header("Content-Type", "application/xml")
                .header("cache-control", " no-cache")
                .header("accept-encoding", "gzip, deflate")
                .asBinary();
        Document dom = new SAXReader().read(response.getBody());
        for (Element job : (List<Element>) dom.getRootElement().elements("job")) {
            if (jobName.equals(job.elementText("name"))) {
                return true;
            }
        }
        return false;
    }
}

